package com.raincat.multimediapicker.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Environment;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Comparator;

/**
 * @author Administrator By GeorgeZ
 */
public class ImageCacheUtils {
    /**
     * 缓存目录
     */
    private static String DATA_PICTURES_PATH = null;
    /**
     * 扩展名
     */
    private static final String CACHE_TAIL = ".jpg";
    /**
     * 最大缓存空间,MB
     */
    private static final int CACHE_SIZE = 30;

    public ImageCacheUtils(Context context) {
        if (DATA_PICTURES_PATH == null)
            DATA_PICTURES_PATH = Environment.getExternalStorageDirectory() + "/Android/data/" + context.getPackageName() + "/files/Pictures";
        File file = new File(DATA_PICTURES_PATH);
        if (!file.exists()) {
            file.mkdirs();
        }
        removeCache();
    }

    /**
     * 把一张bitmap图片写入缓存
     *
     * @param key     获取缓存要的Key
     * @param quality 图片质量
     * @param bm      图片
     */
    public void addBitmapToFile(String key, int quality, Bitmap bm) {
        if (bm == null || key == null) {
            return;
        }
        String filename = convertKeyToFilename(key);
        File file = new File(DATA_PICTURES_PATH, filename);
        try {
            OutputStream out = new FileOutputStream(file);

            if (key.substring(key.lastIndexOf(".") + 1).equalsIgnoreCase("png")) {
                Bitmap outB = bm.copy(Bitmap.Config.RGB_565, true);
                Canvas canvas = new Canvas(outB);
                canvas.drawColor(Color.WHITE);
                canvas.drawBitmap(bm, 0, 0, null);
                outB.compress(CompressFormat.JPEG, quality, out);
            } else
                bm.compress(CompressFormat.JPEG, quality, out);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据Key从缓存中获取图片
     *
     */
    public Bitmap getBitmapFromFileByKey(String key) {
        if (key == null) {
            return null;
        }
        String filename = DATA_PICTURES_PATH + File.separator + convertKeyToFilename(key);
        return getBitmapFromFileByFullPath(filename);
    }

    /**
     * 根据完整路径获取一张图片，
     */
    public Bitmap getBitmapFromFileByFullPath(String Path) {
        if (Path == null) {
            return null;
        }
        String filename = Path;
        File file = new File(filename);
        if (file.exists()) {
            Bitmap bitmap = null;
            try {
                BitmapFactory.Options opt = new BitmapFactory.Options();
                opt.inPreferredConfig = Bitmap.Config.RGB_565;
                bitmap = BitmapFactory.decodeFile(filename, opt);
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
            }
            if (bitmap == null) {
                file.delete();
            } else {
                updateFileModifiedTime(filename);
                return bitmap;
            }
        }
        return null;
    }

    /**
     * 清除40%的缓存，这些缓存被删除的优先级根据近期使用时间排列,越久没被使用，越容易被删除
     *
     */
    private void removeCache() {
        File dir = new File(DATA_PICTURES_PATH);
        File[] files = dir.listFiles();
        if (files == null) {
            return;
        }
        double total_size = 0;
        for (File file : files) {
            total_size += file.length();
        }
        total_size = total_size / 1024 / 1024;
        if (total_size > CACHE_SIZE) {
            int removeFactor = (int) (files.length * 0.4);
            Arrays.sort(files, new FileLastModifiedComparator());
            for (int i = 0; i < removeFactor; i++) {
                files[i].delete();
            }
        }
    }

    /**
     * 获取缓存大小
     *
     * @return
     */
    public double getFileCacheSize() {
        File dir = new File(DATA_PICTURES_PATH);
        File[] files = dir.listFiles();
        if (files == null) {
            return 0.0;
        }
        double total_size = 0;
        for (File file : files) {
            total_size += file.length();
        }
        total_size = total_size / 1024 / 1024;
        return total_size;
    }

    /**
     * 删除缓存
     */
    public void deleteDir() {
        File dir = new File(DATA_PICTURES_PATH);
        if (dir == null || !dir.exists() || !dir.isDirectory())
            return;

        for (File file : dir.listFiles()) {
            if (file.isFile())
                file.delete(); // 删除所有文件
            else if (file.isDirectory())
                deleteDir(); // 递规的方式删除文件夹
        }
        dir.delete();// 删除目录本身
    }

    /**
     * 删除指定文件
     *
     * @param PATH
     */
    public void delFile(String PATH) {
        File file = new File(PATH);
        if (file.isFile()) {
            file.delete();
        }
    }

    /**
     * 将关键字转化为文件名
     */
    private String convertKeyToFilename(String key) {
        if (key == null) {
            return "";
        }
        return key.hashCode() + CACHE_TAIL;
    }

    /**
     * 更新文件最后修改时间
     */
    private void updateFileModifiedTime(String path) {
        File file = new File(path);
        file.setLastModified(System.currentTimeMillis());
    }

    /**
     * 获取缓存图片路径
     *
     * @param key 用于生成哈希值
     * @return 若图片不存在返回null
     */
    public String getCachePath(String key) {
        String path = DATA_PICTURES_PATH + File.separator + convertKeyToFilename(key);
        if (fileIsExists(path))
            return path;
        else
            return null;
    }

    /**
     * 判断文件是否存在
     *
     * @param Path
     * @return
     */
    private boolean fileIsExists(String Path) {
        try {
            File f = new File(Path);
            if (!f.exists()) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 文件大小
     */
    static float getFileSize(String Path) {
        try {
            File f = new File(Path);
            if (f.exists()) {
                return f.length();
            }
        } catch (Exception e) {
            return 0f;
        }
        return 0f;
    }

    private class FileLastModifiedComparator implements Comparator<File> {
        @Override
        public int compare(File lhs, File rhs) {
            if (lhs.lastModified() > rhs.lastModified()) {
                return 1;
            } else if (lhs.lastModified() == rhs.lastModified()) {
                return 0;
            } else {
                return -1;
            }
        }
    }
}
